<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>飞鹤API测试页面</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        
        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            min-height: 100vh;
            padding: 20px;
        }
        
        .container {
            max-width: 1200px;
            margin: 0 auto;
            background: white;
            border-radius: 15px;
            box-shadow: 0 20px 60px rgba(0,0,0,0.1);
            overflow: hidden;
        }
        
        .header {
            background: linear-gradient(135deg, #4CAF50 0%, #45a049 100%);
            color: white;
            padding: 30px;
            text-align: center;
        }
        
        .header h1 {
            font-size: 2.5em;
            margin-bottom: 10px;
        }
        
        .header p {
            font-size: 1.1em;
            opacity: 0.9;
        }
        
        .content {
            padding: 30px;
        }
        
        .section {
            margin-bottom: 40px;
            padding: 25px;
            border: 2px solid #f0f0f0;
            border-radius: 10px;
            background: #fafafa;
        }
        
        .section h2 {
            color: #333;
            margin-bottom: 20px;
            padding-bottom: 10px;
            border-bottom: 3px solid #4CAF50;
            display: inline-block;
        }
        
        .form-group {
            margin-bottom: 20px;
        }
        
        .form-group label {
            display: block;
            margin-bottom: 8px;
            font-weight: bold;
            color: #555;
        }
        
        .form-group input, .form-group textarea, .form-group select {
            width: 100%;
            padding: 12px;
            border: 2px solid #ddd;
            border-radius: 8px;
            font-size: 14px;
            transition: border-color 0.3s;
        }
        
        .form-group input:focus, .form-group textarea:focus, .form-group select:focus {
            outline: none;
            border-color: #4CAF50;
        }
        
        .form-group textarea {
            height: 120px;
            resize: vertical;
        }
        
        .btn {
            background: linear-gradient(135deg, #4CAF50 0%, #45a049 100%);
            color: white;
            border: none;
            padding: 12px 25px;
            border-radius: 8px;
            cursor: pointer;
            font-size: 16px;
            margin-right: 10px;
            margin-bottom: 10px;
            transition: transform 0.2s;
        }
        
        .btn:hover {
            transform: translateY(-2px);
            box-shadow: 0 5px 15px rgba(76, 175, 80, 0.3);
        }
        
        .btn-secondary {
            background: linear-gradient(135deg, #2196F3 0%, #1976D2 100%);
        }
        
        .btn-danger {
            background: linear-gradient(135deg, #f44336 0%, #d32f2f 100%);
        }
        
        .result {
            background: #f8f9fa;
            border: 2px solid #e9ecef;
            border-radius: 8px;
            padding: 15px;
            margin-top: 20px;
            max-height: 300px;
            overflow-y: auto;
        }
        
        .result h3 {
            color: #333;
            margin-bottom: 10px;
        }
        
        .result pre {
            background: #2d3748;
            color: #e2e8f0;
            padding: 15px;
            border-radius: 5px;
            overflow-x: auto;
            font-size: 13px;
            line-height: 1.4;
        }
        
        .grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
            gap: 30px;
        }
        
        .encryption-section {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
        }
        
        .encryption-section h2 {
            border-bottom-color: white;
            color: white;
        }
        
        .encryption-section .form-group input,
        .encryption-section .form-group textarea {
            background: rgba(255,255,255,0.1);
            border-color: rgba(255,255,255,0.3);
            color: white;
        }
        
        .encryption-section .form-group input::placeholder,
        .encryption-section .form-group textarea::placeholder {
            color: rgba(255,255,255,0.7);
        }
        
        .loading {
            display: none;
            color: #4CAF50;
            font-weight: bold;
        }
        
        .api-grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
            gap: 25px;
        }
        
        .status-success {
            color: #4CAF50;
            font-weight: bold;
        }
        
        .status-error {
            color: #f44336;
            font-weight: bold;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1>🚀 飞鹤API测试页面</h1>
            <p>支持AES加密的完整API接口测试工具</p>
        </div>
        
        <div class="content">
            <!-- AES加密/解密区域 -->
            <div class="section encryption-section">
                <h2>🔐 AES加密/解密</h2>
                <div class="grid">
                    <div>
                        <div class="form-group">
                            <label for="aesKey">AES密钥 (32位):</label>
                            <input type="text" id="aesKey" value="feihe2024reservation123456789012" placeholder="请输入32位AES密钥">
                        </div>
                        <div class="form-group">
                            <label for="plainText">明文:</label>
                            <textarea id="plainText" placeholder='请输入要加密的JSON数据，例如：{"memberId":"CRM000000000190071474"}'></textarea>
                        </div>
                        <button class="btn" onclick="encryptData()">🔒 加密</button>
                        <button class="btn btn-secondary" onclick="decryptData()">🔓 解密</button>
                        <button class="btn btn-danger" onclick="clearEncryption()">🗑️ 清空</button>
                    </div>
                    <div>
                        <div class="form-group">
                            <label for="encryptedText">密文:</label>
                            <textarea id="encryptedText" placeholder="加密结果将显示在这里"></textarea>
                        </div>
                        <div class="result">
                            <h3>加密/解密结果:</h3>
                            <pre id="encryptionResult">等待操作...</pre>
                        </div>
                    </div>
                </div>
            </div>
            
            <!-- API测试区域 -->
            <div class="section">
                <h2>🌐 API接口测试</h2>
                <div class="form-group">
                    <label for="baseUrl">API基础URL:</label>
                    <input type="text" id="baseUrl" value="/feihe">
                </div>
                <div class="form-group">
                    <label>
                        <input type="checkbox" id="useEncryption"> 启用AES加密传输
                    </label>
                </div>
                
                <div class="api-grid">
                    <!-- 1. get_day -->
                    <div class="api-item">
                        <h3>📅 获取未来7天信息</h3>
                        <div class="form-group">
                            <label>请求参数:</label>
                            <textarea id="getDay_params">{"memberId": "CRM000000000190071474"}</textarea>
                        </div>
                        <button class="btn" onclick="callAPI('get_day', 'getDay_params', 'getDay_result')">发送请求</button>
                        <div class="loading" id="getDay_loading">发送中...</div>
                        <div class="result" id="getDay_result">
                            <h3>响应结果:</h3>
                            <pre>等待请求...</pre>
                        </div>
                    </div>
                    
                    <!-- 2. get_ground -->
                    <div class="api-item">
                        <h3>🏭 获取场地信息</h3>
                        <div class="form-group">
                            <label>请求参数:</label>
                            <textarea id="getGround_params">{"memberId": "CRM000000000190071474"}</textarea>
                        </div>
                        <button class="btn" onclick="callAPI('get_ground', 'getGround_params', 'getGround_result')">发送请求</button>
                        <div class="loading" id="getGround_loading">发送中...</div>
                        <div class="result" id="getGround_result">
                            <h3>响应结果:</h3>
                            <pre>等待请求...</pre>
                        </div>
                    </div>
                    
                    <!-- 3. get_time -->
                    <div class="api-item">
                        <h3>⏰ 获取时间段信息</h3>
                        <div class="form-group">
                            <label>请求参数:</label>
                            <textarea id="getTime_params">{"day": "2025-07-24", "ground": 1, "memberId": "CRM000000000190071474"}</textarea>
                        </div>
                        <button class="btn" onclick="callAPI('get_time', 'getTime_params', 'getTime_result')">发送请求</button>
                        <div class="loading" id="getTime_loading">发送中...</div>
                        <div class="result" id="getTime_result">
                            <h3>响应结果:</h3>
                            <pre>等待请求...</pre>
                        </div>
                    </div>
                    
                    <!-- 4. reservation -->
                    <div class="api-item">
                        <h3>📝 创建预约</h3>
                        <div class="form-group">
                            <label>请求参数:</label>
                            <textarea id="reservation_params">{"ground": 2, "memberId": "CRM000000000190071474", "realname": "测试用户", "reservation_date": "2025-07-24", "reservation_time": "12:00-13:00", "telephone": "13800138000", "type": "3", "visitor_number": 5}</textarea>
                        </div>
                        <button class="btn" onclick="callAPI('reservation', 'reservation_params', 'reservation_result')">发送请求</button>
                        <div class="loading" id="reservation_loading">发送中...</div>
                        <div class="result" id="reservation_result">
                            <h3>响应结果:</h3>
                            <pre>等待请求...</pre>
                        </div>
                    </div>
                    
                    <!-- 5. reservation_detail -->
                    <div class="api-item">
                        <h3>📋 获取预约详情</h3>
                        <div class="form-group">
                            <label>请求参数:</label>
                            <textarea id="reservationDetail_params">{"id": "24", "memberId": "CRM000000000190071474"}</textarea>
                        </div>
                        <button class="btn" onclick="callAPI('reservation_detail', 'reservationDetail_params', 'reservationDetail_result')">发送请求</button>
                        <div class="loading" id="reservationDetail_loading">发送中...</div>
                        <div class="result" id="reservationDetail_result">
                            <h3>响应结果:</h3>
                            <pre>等待请求...</pre>
                        </div>
                    </div>
                    
                    <!-- 6. reservation_cancel -->
                    <div class="api-item">
                        <h3>❌ 取消预约</h3>
                        <div class="form-group">
                            <label>请求参数:</label>
                            <textarea id="reservationCancel_params">{"id": "24", "memberId": "CRM000000000190071474"}</textarea>
                        </div>
                        <button class="btn btn-danger" onclick="callAPI('reservation_cancel', 'reservationCancel_params', 'reservationCancel_result')">发送请求</button>
                        <div class="loading" id="reservationCancel_loading">发送中...</div>
                        <div class="result" id="reservationCancel_result">
                            <h3>响应结果:</h3>
                            <pre>等待请求...</pre>
                        </div>
                    </div>
                    
                    <!-- 7. reservation_list -->
                    <div class="api-item">
                        <h3>📊 获取预约列表</h3>
                        <div class="form-group">
                            <label>请求参数:</label>
                            <textarea id="reservationList_params">{"type": 1, "memberId": "CRM000000000190071474"}</textarea>
                        </div>
                        <button class="btn" onclick="callAPI('reservation_list', 'reservationList_params', 'reservationList_result')">发送请求</button>
                        <div class="loading" id="reservationList_loading">发送中...</div>
                        <div class="result" id="reservationList_result">
                            <h3>响应结果:</h3>
                            <pre>等待请求...</pre>
                        </div>
                    </div>
                    
                    <!-- 8. reservation_check -->
                    <div class="api-item">
                        <h3>✅ 签到</h3>
                        <div class="form-group">
                            <label>请求参数:</label>
                            <textarea id="reservationCheck_params">{"uniqid": "1753287834795373"}</textarea>
                        </div>
                        <button class="btn btn-secondary" onclick="callAPI('reservation_check', 'reservationCheck_params', 'reservationCheck_result')">发送请求</button>
                        <div class="loading" id="reservationCheck_loading">发送中...</div>
                        <div class="result" id="reservationCheck_result">
                            <h3>响应结果:</h3>
                            <pre>等待请求...</pre>
                        </div>
                    </div>
                    
                    <!-- 9. test_encryption - 新增加密测试接口 -->
                    <div class="api-item" style="border: 2px solid #FF9800;">
                        <h3>🔐 AES加密测试</h3>
                        <div class="form-group">
                            <label>请求参数:</label>
                            <textarea id="testEncryption_params">{"message": "Hello AES!", "memberId": "CRM000000000190071474", "testData": {"number": 123, "array": [1,2,3]}}</textarea>
                        </div>
                        <button class="btn" style="background: linear-gradient(135deg, #FF9800 0%, #F57C00 100%);" onclick="callAPI('test_encryption', 'testEncryption_params', 'testEncryption_result')">测试加密</button>
                        <div class="loading" id="testEncryption_loading">发送中...</div>
                        <div class="result" id="testEncryption_result">
                            <h3>响应结果:</h3>
                            <pre>等待请求...</pre>
                        </div>
                    </div>
                </div>
                
                <!-- 批量测试 -->
                <div style="margin-top: 30px; text-align: center;">
                    <button class="btn" onclick="testAllAPIs()" style="font-size: 18px; padding: 15px 30px;">🚀 批量测试所有接口</button>
                </div>
            </div>
        </div>
    </div>

    <script>
        // AES加密功能
        function encryptData() {
            const key = document.getElementById('aesKey').value;
            const plainText = document.getElementById('plainText').value;
            
            if (!key || !plainText) {
                alert('请填写密钥和明文');
                return;
            }
            
            try {
                // 验证JSON格式
                JSON.parse(plainText);
                
                // 检查密钥长度
                if (key.length !== 32) {
                    throw new Error('密钥必须是32字节长度');
                }
                
                // AES加密 - 使用ECB模式与后端兼容
                const keyBytes = CryptoJS.enc.Utf8.parse(key);
                const encrypted = CryptoJS.AES.encrypt(plainText, keyBytes, {
                    mode: CryptoJS.mode.ECB,
                    padding: CryptoJS.pad.Pkcs7
                }).toString();
                
                document.getElementById('encryptedText').value = encrypted;
                
                document.getElementById('encryptionResult').textContent = 
                    `✅ 加密成功 (ECB模式)\n明文长度: ${plainText.length}\n密文长度: ${encrypted.length}\n加密时间: ${new Date().toLocaleString()}`;
            } catch (e) {
                document.getElementById('encryptionResult').textContent = `❌ 加密失败: ${e.message}`;
            }
        }
        
        function decryptData() {
            const key = document.getElementById('aesKey').value;
            const encryptedText = document.getElementById('encryptedText').value;
            
            if (!key || !encryptedText) {
                alert('请填写密钥和密文');
                return;
            }
            
            try {
                // 检查密钥长度
                if (key.length !== 32) {
                    throw new Error('密钥必须是32字节长度');
                }
                
                // AES解密 - 使用ECB模式与后端兼容
                const keyBytes = CryptoJS.enc.Utf8.parse(key);
                const decrypted = CryptoJS.AES.decrypt(encryptedText, keyBytes, {
                    mode: CryptoJS.mode.ECB,
                    padding: CryptoJS.pad.Pkcs7
                }).toString(CryptoJS.enc.Utf8);
                
                document.getElementById('plainText').value = decrypted;
                
                document.getElementById('encryptionResult').textContent = 
                    `✅ 解密成功 (ECB模式)\n密文长度: ${encryptedText.length}\n明文长度: ${decrypted.length}\n解密时间: ${new Date().toLocaleString()}`;
            } catch (e) {
                document.getElementById('encryptionResult').textContent = `❌ 解密失败: ${e.message}`;
            }
        }
        
        function clearEncryption() {
            document.getElementById('plainText').value = '';
            document.getElementById('encryptedText').value = '';
            document.getElementById('encryptionResult').textContent = '等待操作...';
        }
        
        // API调用功能
        async function callAPI(endpoint, paramsId, resultId) {
            const baseUrl = document.getElementById('baseUrl').value;
            const useEncryption = document.getElementById('useEncryption').checked;
            const params = document.getElementById(paramsId).value;
            const loadingId = paramsId.replace('_params', '_loading');
            
            // 显示加载状态
            document.getElementById(loadingId).style.display = 'block';
            
            try {
                // 验证JSON格式
                const jsonData = JSON.parse(params);
                
                let requestBody;
                if (useEncryption) {
                    const key = document.getElementById('aesKey').value;
                    if (!key) {
                        throw new Error('启用加密时必须设置AES密钥');
                    }
                    if (key.length !== 32) {
                        throw new Error('密钥必须是32字节长度');
                    }
                    
                    // 使用ECB模式加密，与后端兼容
                    const keyBytes = CryptoJS.enc.Utf8.parse(key);
                    const encrypted = CryptoJS.AES.encrypt(params, keyBytes, {
                        mode: CryptoJS.mode.ECB,
                        padding: CryptoJS.pad.Pkcs7
                    }).toString();
                    
                    requestBody = {
                        encrypted: encrypted
                    };
                } else {
                    requestBody = jsonData;
                }
                
                const startTime = Date.now();
                
                const response = await fetch(`${baseUrl}/${endpoint}`, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                    },
                    body: JSON.stringify(requestBody)
                });
                
                const responseTime = Date.now() - startTime;
                const responseData = await response.json();
                
                // 处理响应
                let displayData = responseData;
                if (useEncryption && responseData.encrypted) {
                    try {
                        const key = document.getElementById('aesKey').value;
                        const keyBytes = CryptoJS.enc.Utf8.parse(key);
                        const decryptedResponse = CryptoJS.AES.decrypt(responseData.encrypted, keyBytes, {
                            mode: CryptoJS.mode.ECB,
                            padding: CryptoJS.pad.Pkcs7
                        }).toString(CryptoJS.enc.Utf8);
                        displayData = JSON.parse(decryptedResponse);
                    } catch (e) {
                        displayData = {
                            ...responseData,
                            decryptError: '响应解密失败: ' + e.message
                        };
                    }
                }
                
                const statusClass = response.ok ? 'status-success' : 'status-error';
                const result = {
                    status: response.status,
                    statusText: response.statusText,
                    responseTime: responseTime + 'ms',
                    data: displayData,
                    timestamp: new Date().toLocaleString()
                };
                
                document.getElementById(resultId).innerHTML = `
                    <h3 class="${statusClass}">响应结果 (${response.status} ${response.statusText}):</h3>
                    <pre>${JSON.stringify(result, null, 2)}</pre>
                `;
                
            } catch (error) {
                document.getElementById(resultId).innerHTML = `
                    <h3 class="status-error">请求失败:</h3>
                    <pre>${error.message}</pre>
                `;
            } finally {
                // 隐藏加载状态
                document.getElementById(loadingId).style.display = 'none';
            }
        }
        
        // 批量测试所有接口
        async function testAllAPIs() {
            const apis = [
                'get_day', 'get_ground', 'get_time', 'reservation',
                'reservation_detail', 'reservation_cancel', 'reservation_list', 'reservation_check', 'test_encryption'
            ];
            
            const paramIds = [
                'getDay_params', 'getGround_params', 'getTime_params', 'reservation_params',
                'reservationDetail_params', 'reservationCancel_params', 'reservationList_params', 'reservationCheck_params', 'testEncryption_params'
            ];
            
            const resultIds = [
                'getDay_result', 'getGround_result', 'getTime_result', 'reservation_result',
                'reservationDetail_result', 'reservationCancel_result', 'reservationList_result', 'reservationCheck_result', 'testEncryption_result'
            ];
            
            for (let i = 0; i < apis.length; i++) {
                console.log(`Testing ${apis[i]}...`);
                await callAPI(apis[i], paramIds[i], resultIds[i]);
                // 添加短暂延迟避免请求过快
                await new Promise(resolve => setTimeout(resolve, 500));
            }
            
            alert('✅ 批量测试完成！');
        }
        
        // 页面加载完成后的初始化
        document.addEventListener('DOMContentLoaded', function() {
            console.log('🚀 飞鹤API测试页面已加载');
            
            // 设置默认的AES密钥
            document.getElementById('aesKey').value = 'feihe2024reservation123456789012';
            
            // 设置示例数据
            document.getElementById('plainText').value = '{"memberId": "CRM000000000190071474", "message": "Hello Feihe!"}';
        });
    </script>
</body>
</html> 